/*
 * Copyright (C) 1997-2001 Id Software, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * 
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA.
 *  
 */
/* Modifications
   Copyright 2003-2004 Bytonic Software
   Copyright 2010 Google Inc.
*/
package com.googlecode.playnquake.core.game.monsters;

import com.googlecode.playnquake.core.common.Constants;
import com.googlecode.playnquake.core.game.*;
import com.googlecode.playnquake.core.game.adapters.EntInteractAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityDieAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityPainAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityThinkAdapter;
import com.googlecode.playnquake.core.server.ServerGame;
import com.googlecode.playnquake.core.server.ServerInit;
import com.googlecode.playnquake.core.server.World;
import com.googlecode.playnquake.core.util.Lib;
import com.googlecode.playnquake.core.util.Math3D;


public class MonsterFlyer {
    //	This file generated by ModelGen - Do NOT Modify

    public final static int ACTION_nothing = 0;

    public final static int ACTION_attack1 = 1;

    public final static int ACTION_attack2 = 2;

    public final static int ACTION_run = 3;

    public final static int ACTION_walk = 4;

    public final static int FRAME_start01 = 0;

    public final static int FRAME_start02 = 1;

    public final static int FRAME_start03 = 2;

    public final static int FRAME_start04 = 3;

    public final static int FRAME_start05 = 4;

    public final static int FRAME_start06 = 5;

    public final static int FRAME_stop01 = 6;

    public final static int FRAME_stop02 = 7;

    public final static int FRAME_stop03 = 8;

    public final static int FRAME_stop04 = 9;

    public final static int FRAME_stop05 = 10;

    public final static int FRAME_stop06 = 11;

    public final static int FRAME_stop07 = 12;

    public final static int FRAME_stand01 = 13;

    public final static int FRAME_stand02 = 14;

    public final static int FRAME_stand03 = 15;

    public final static int FRAME_stand04 = 16;

    public final static int FRAME_stand05 = 17;

    public final static int FRAME_stand06 = 18;

    public final static int FRAME_stand07 = 19;

    public final static int FRAME_stand08 = 20;

    public final static int FRAME_stand09 = 21;

    public final static int FRAME_stand10 = 22;

    public final static int FRAME_stand11 = 23;

    public final static int FRAME_stand12 = 24;

    public final static int FRAME_stand13 = 25;

    public final static int FRAME_stand14 = 26;

    public final static int FRAME_stand15 = 27;

    public final static int FRAME_stand16 = 28;

    public final static int FRAME_stand17 = 29;

    public final static int FRAME_stand18 = 30;

    public final static int FRAME_stand19 = 31;

    public final static int FRAME_stand20 = 32;

    public final static int FRAME_stand21 = 33;

    public final static int FRAME_stand22 = 34;

    public final static int FRAME_stand23 = 35;

    public final static int FRAME_stand24 = 36;

    public final static int FRAME_stand25 = 37;

    public final static int FRAME_stand26 = 38;

    public final static int FRAME_stand27 = 39;

    public final static int FRAME_stand28 = 40;

    public final static int FRAME_stand29 = 41;

    public final static int FRAME_stand30 = 42;

    public final static int FRAME_stand31 = 43;

    public final static int FRAME_stand32 = 44;

    public final static int FRAME_stand33 = 45;

    public final static int FRAME_stand34 = 46;

    public final static int FRAME_stand35 = 47;

    public final static int FRAME_stand36 = 48;

    public final static int FRAME_stand37 = 49;

    public final static int FRAME_stand38 = 50;

    public final static int FRAME_stand39 = 51;

    public final static int FRAME_stand40 = 52;

    public final static int FRAME_stand41 = 53;

    public final static int FRAME_stand42 = 54;

    public final static int FRAME_stand43 = 55;

    public final static int FRAME_stand44 = 56;

    public final static int FRAME_stand45 = 57;

    public final static int FRAME_attak101 = 58;

    public final static int FRAME_attak102 = 59;

    public final static int FRAME_attak103 = 60;

    public final static int FRAME_attak104 = 61;

    public final static int FRAME_attak105 = 62;

    public final static int FRAME_attak106 = 63;

    public final static int FRAME_attak107 = 64;

    public final static int FRAME_attak108 = 65;

    public final static int FRAME_attak109 = 66;

    public final static int FRAME_attak110 = 67;

    public final static int FRAME_attak111 = 68;

    public final static int FRAME_attak112 = 69;

    public final static int FRAME_attak113 = 70;

    public final static int FRAME_attak114 = 71;

    public final static int FRAME_attak115 = 72;

    public final static int FRAME_attak116 = 73;

    public final static int FRAME_attak117 = 74;

    public final static int FRAME_attak118 = 75;

    public final static int FRAME_attak119 = 76;

    public final static int FRAME_attak120 = 77;

    public final static int FRAME_attak121 = 78;

    public final static int FRAME_attak201 = 79;

    public final static int FRAME_attak202 = 80;

    public final static int FRAME_attak203 = 81;

    public final static int FRAME_attak204 = 82;

    public final static int FRAME_attak205 = 83;

    public final static int FRAME_attak206 = 84;

    public final static int FRAME_attak207 = 85;

    public final static int FRAME_attak208 = 86;

    public final static int FRAME_attak209 = 87;

    public final static int FRAME_attak210 = 88;

    public final static int FRAME_attak211 = 89;

    public final static int FRAME_attak212 = 90;

    public final static int FRAME_attak213 = 91;

    public final static int FRAME_attak214 = 92;

    public final static int FRAME_attak215 = 93;

    public final static int FRAME_attak216 = 94;

    public final static int FRAME_attak217 = 95;

    public final static int FRAME_bankl01 = 96;

    public final static int FRAME_bankl02 = 97;

    public final static int FRAME_bankl03 = 98;

    public final static int FRAME_bankl04 = 99;

    public final static int FRAME_bankl05 = 100;

    public final static int FRAME_bankl06 = 101;

    public final static int FRAME_bankl07 = 102;

    public final static int FRAME_bankr01 = 103;

    public final static int FRAME_bankr02 = 104;

    public final static int FRAME_bankr03 = 105;

    public final static int FRAME_bankr04 = 106;

    public final static int FRAME_bankr05 = 107;

    public final static int FRAME_bankr06 = 108;

    public final static int FRAME_bankr07 = 109;

    public final static int FRAME_rollf01 = 110;

    public final static int FRAME_rollf02 = 111;

    public final static int FRAME_rollf03 = 112;

    public final static int FRAME_rollf04 = 113;

    public final static int FRAME_rollf05 = 114;

    public final static int FRAME_rollf06 = 115;

    public final static int FRAME_rollf07 = 116;

    public final static int FRAME_rollf08 = 117;

    public final static int FRAME_rollf09 = 118;

    public final static int FRAME_rollr01 = 119;

    public final static int FRAME_rollr02 = 120;

    public final static int FRAME_rollr03 = 121;

    public final static int FRAME_rollr04 = 122;

    public final static int FRAME_rollr05 = 123;

    public final static int FRAME_rollr06 = 124;

    public final static int FRAME_rollr07 = 125;

    public final static int FRAME_rollr08 = 126;

    public final static int FRAME_rollr09 = 127;

    public final static int FRAME_defens01 = 128;

    public final static int FRAME_defens02 = 129;

    public final static int FRAME_defens03 = 130;

    public final static int FRAME_defens04 = 131;

    public final static int FRAME_defens05 = 132;

    public final static int FRAME_defens06 = 133;

    public final static int FRAME_pain101 = 134;

    public final static int FRAME_pain102 = 135;

    public final static int FRAME_pain103 = 136;

    public final static int FRAME_pain104 = 137;

    public final static int FRAME_pain105 = 138;

    public final static int FRAME_pain106 = 139;

    public final static int FRAME_pain107 = 140;

    public final static int FRAME_pain108 = 141;

    public final static int FRAME_pain109 = 142;

    public final static int FRAME_pain201 = 143;

    public final static int FRAME_pain202 = 144;

    public final static int FRAME_pain203 = 145;

    public final static int FRAME_pain204 = 146;

    public final static int FRAME_pain301 = 147;

    public final static int FRAME_pain302 = 148;

    public final static int FRAME_pain303 = 149;

    public final static int FRAME_pain304 = 150;

    public final static float MODEL_SCALE = 1.000000f;

    static int nextmove; // Used for start/stop frames

    static int sound_sight;

    static int sound_idle;

    static int sound_pain1;

    static int sound_pain2;

    static int sound_slash;

    static int sound_sproing;

    static int sound_die;

    public static EntInteractAdapter flyer_sight = new EntInteractAdapter() {
    	public String getID() { return "flyer_sight"; }
        public boolean interact(Entity self, Entity other) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_sight, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter flyer_idle = new EntityThinkAdapter() {
    	public String getID() { return "flyer_idle"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_idle, (float) 1, (float) Constants.ATTN_IDLE,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter flyer_pop_blades = new EntityThinkAdapter() {
    	public String getID() { return "flyer_pop_blades"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_sproing, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static Frame flyer_frames_stand[] = new Frame[] {
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null) };

    static MonsterMove flyer_move_stand = new MonsterMove(FRAME_stand01, FRAME_stand45,
            flyer_frames_stand, null);

    static Frame flyer_frames_walk[] = new Frame[] {
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null) };

    static MonsterMove flyer_move_walk = new MonsterMove(FRAME_stand01, FRAME_stand45,
            flyer_frames_walk, null);

    static Frame flyer_frames_run[] = new Frame[] {
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null),
            new Frame(GameAI.ai_run, 10, null) };

    static MonsterMove flyer_move_run = new MonsterMove(FRAME_stand01, FRAME_stand45,
            flyer_frames_run, null);

    static EntityThinkAdapter flyer_run = new EntityThinkAdapter() {
    	public String getID() { return "flyer_run"; }
        public boolean think(Entity self) {
            if ((self.monsterinfo.aiflags & Constants.AI_STAND_GROUND) != 0)
                self.monsterinfo.currentmove = flyer_move_stand;
            else
                self.monsterinfo.currentmove = flyer_move_run;
            return true;
        }
    };

    static EntityThinkAdapter flyer_walk = new EntityThinkAdapter() {
    	public String getID() { return "flyer_walk"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = flyer_move_walk;
            return true;
        }
    };

    static EntityThinkAdapter flyer_stand = new EntityThinkAdapter() {
    	public String getID() { return "flyer_stand"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = flyer_move_stand;
            return true;
        }
    };

    static EntityThinkAdapter flyer_nextmove = new EntityThinkAdapter() {
    	public String getID() { return "flyer_nextmove"; }
        public boolean think(Entity self) {
            if (nextmove == ACTION_attack1)
                self.monsterinfo.currentmove = flyer_move_start_melee;
            else if (nextmove == ACTION_attack2)
                self.monsterinfo.currentmove = flyer_move_attack2;
            else if (nextmove == ACTION_run)
                self.monsterinfo.currentmove = flyer_move_run;
            return true;
        }
    };

    static Frame flyer_frames_start[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, flyer_nextmove) };

    static MonsterMove flyer_move_start = new MonsterMove(FRAME_start01, FRAME_start06,
            flyer_frames_start, null);

    static Frame flyer_frames_stop[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, flyer_nextmove) };

    static MonsterMove flyer_move_stop = new MonsterMove(FRAME_stop01, FRAME_stop07,
            flyer_frames_stop, null);

    static EntityThinkAdapter flyer_stop = new EntityThinkAdapter() {
    	public String getID() { return "flyer_stop"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = flyer_move_stop;
            return true;
        }
    };

    static EntityThinkAdapter flyer_start = new EntityThinkAdapter() {
    	public String getID() { return "flyer_start"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = flyer_move_start;
            return true;
        }
    };

    static Frame flyer_frames_rollright[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_rollright = new MonsterMove(FRAME_rollr01,
            FRAME_rollr09, flyer_frames_rollright, null);

    static Frame flyer_frames_rollleft[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_rollleft = new MonsterMove(FRAME_rollf01,
            FRAME_rollf09, flyer_frames_rollleft, null);

    static Frame flyer_frames_pain3[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_pain3 = new MonsterMove(FRAME_pain301, FRAME_pain304,
            flyer_frames_pain3, flyer_run);

    static Frame flyer_frames_pain2[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_pain2 = new MonsterMove(FRAME_pain201, FRAME_pain204,
            flyer_frames_pain2, flyer_run);

    static Frame flyer_frames_pain1[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_pain1 = new MonsterMove(FRAME_pain101, FRAME_pain109,
            flyer_frames_pain1, flyer_run);

    static Frame flyer_frames_defense[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            // Hold this frame
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_defense = new MonsterMove(FRAME_defens01,
            FRAME_defens06, flyer_frames_defense, null);

    static Frame flyer_frames_bankright[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_bankright = new MonsterMove(FRAME_bankr01,
            FRAME_bankr07, flyer_frames_bankright, null);

    static Frame flyer_frames_bankleft[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove flyer_move_bankleft = new MonsterMove(FRAME_bankl01,
            FRAME_bankl07, flyer_frames_bankleft, null);

    static EntityThinkAdapter flyer_fireleft = new EntityThinkAdapter() {
    	public String getID() { return "flyer_fireleft"; }
        public boolean think(Entity self) {
            flyer_fire(self, Constants.MZ2_FLYER_BLASTER_1);
            return true;
        }
    };

    static EntityThinkAdapter flyer_fireright = new EntityThinkAdapter() {
    	public String getID() { return "flyer_fireright"; }
        public boolean think(Entity self) {
            flyer_fire(self, Constants.MZ2_FLYER_BLASTER_2);
            return true;
        }
    };

    static Frame flyer_frames_attack2[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, -10, flyer_fireleft),
            // left gun
            new Frame(GameAI.ai_charge, -10, flyer_fireright), // right gun
            new Frame(GameAI.ai_charge, -10, flyer_fireleft), // left gun
            new Frame(GameAI.ai_charge, -10, flyer_fireright), // right gun
            new Frame(GameAI.ai_charge, -10, flyer_fireleft), // left gun
            new Frame(GameAI.ai_charge, -10, flyer_fireright), // right gun
            new Frame(GameAI.ai_charge, -10, flyer_fireleft), // left gun
            new Frame(GameAI.ai_charge, -10, flyer_fireright), // right gun
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) };

    static MonsterMove flyer_move_attack2 = new MonsterMove(FRAME_attak201,
            FRAME_attak217, flyer_frames_attack2, flyer_run);

    static EntityThinkAdapter flyer_slash_left = new EntityThinkAdapter() {
    	public String getID() { return "flyer_slash_left"; }
        public boolean think(Entity self) {
            float[] aim = { 0, 0, 0 };

            Math3D.VectorSet(aim, Constants.MELEE_DISTANCE, self.mins[0], 0);
            GameWeapon.fire_hit(self, aim, 5, 0);
            ServerGame.PF_StartSound(self, Constants.CHAN_WEAPON, sound_slash, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter flyer_slash_right = new EntityThinkAdapter() {
    	public String getID() { return "flyer_slash_right"; }
        public boolean think(Entity self) {
            float[] aim = { 0, 0, 0 };

            Math3D.VectorSet(aim, Constants.MELEE_DISTANCE, self.maxs[0], 0);
            GameWeapon.fire_hit(self, aim, 5, 0);
            ServerGame.PF_StartSound(self, Constants.CHAN_WEAPON, sound_slash, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter flyer_loop_melee = new EntityThinkAdapter() {
    	public String getID() { return "flyer_loop_melee"; }
        public boolean think(Entity self) {
            /*
             * if (random() <= 0.5) self.monsterinfo.currentmove =
             * flyer_move_attack1; else
             */
            self.monsterinfo.currentmove = flyer_move_loop_melee;
            return true;
        }
    };

    static Frame flyer_frames_start_melee[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, flyer_pop_blades),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) };

    static MonsterMove flyer_move_start_melee = new MonsterMove(FRAME_attak101,
            FRAME_attak106, flyer_frames_start_melee, flyer_loop_melee);

    static Frame flyer_frames_end_melee[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) };

    static MonsterMove flyer_move_end_melee = new MonsterMove(FRAME_attak119,
            FRAME_attak121, flyer_frames_end_melee, flyer_run);

    static Frame flyer_frames_loop_melee[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null), // Loop Start
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, flyer_slash_left),
            // Left Wing Strike
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, flyer_slash_right),
            // Right Wing Strike
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) // Loop Ends

    };

    static EntityThinkAdapter flyer_check_melee = new EntityThinkAdapter() {
    	public String getID() { return "flyer_check_melee"; }
        public boolean think(Entity self) {
            if (GameUtil.range(self, self.enemy) == Constants.RANGE_MELEE)
                if (Lib.random() <= 0.8)
                    self.monsterinfo.currentmove = flyer_move_loop_melee;
                else
                    self.monsterinfo.currentmove = flyer_move_end_melee;
            else
                self.monsterinfo.currentmove = flyer_move_end_melee;
            return true;
        }
    };

    static MonsterMove flyer_move_loop_melee = new MonsterMove(FRAME_attak107,
            FRAME_attak118, flyer_frames_loop_melee, flyer_check_melee);

    static EntityThinkAdapter flyer_attack = new EntityThinkAdapter() {
    	public String getID() { return "flyer_attack"; }
        public boolean think(Entity self) {
            /*
             * if (random() <= 0.5) self.monsterinfo.currentmove =
             * flyer_move_attack1; else
             */
            self.monsterinfo.currentmove = flyer_move_attack2;

            return true;
        }
    };

    static EntityThinkAdapter flyer_setstart = new EntityThinkAdapter() {
    	public String getID() { return "flyer_setstart"; }
        public boolean think(Entity self) {
            nextmove = ACTION_run;
            self.monsterinfo.currentmove = flyer_move_start;
            return true;
        }
    };

    static EntityThinkAdapter flyer_melee = new EntityThinkAdapter() {
    	public String getID() { return "flyer_melee"; }
        public boolean think(Entity self) {
            //			flyer.nextmove = ACTION_attack1;
            //	 self.monsterinfo.currentmove = flyer_move_stop;
            self.monsterinfo.currentmove = flyer_move_start_melee;
            return true;
        }
    };

    static EntityPainAdapter flyer_pain = new EntityPainAdapter() {
    	public String getID() { return "flyer_pain"; }
        public void pain(Entity self, Entity other, float kick, int damage) {
            int n;

            if (self.health < (self.max_health / 2))
                self.s.skinnum = 1;

            if (GameBase.level.time < self.pain_debounce_time)
                return;

            self.pain_debounce_time = GameBase.level.time + 3;
            if (GameBase.skill.value == 3)
                return; // no pain anims in nightmare

            n = Lib.rand() % 3;
            if (n == 0) {
                ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_pain1, (float) 1, (float) Constants.ATTN_NORM,
                (float) 0);
                self.monsterinfo.currentmove = flyer_move_pain1;
            } else if (n == 1) {
                ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_pain2, (float) 1, (float) Constants.ATTN_NORM,
                (float) 0);
                self.monsterinfo.currentmove = flyer_move_pain2;
            } else {
                ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_pain1, (float) 1, (float) Constants.ATTN_NORM,
                (float) 0);
                self.monsterinfo.currentmove = flyer_move_pain3;
            }

        }
    };

    static EntityDieAdapter flyer_die = new EntityDieAdapter() {
    	public String getID() { return "flyer_die"; }
        public void die(Entity self, Entity inflictor, Entity attacker,
                int damage, float[] point) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_die, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            GameMisc.BecomeExplosion1(self);
        }
    };

    static void flyer_fire(Entity self, int flash_number) {
        float[] start = { 0, 0, 0 };

        float[] forward = { 0, 0, 0 }, right = { 0, 0, 0 };
        float[] end = { 0, 0, 0 };
        float[] dir = { 0, 0, 0 };
        int effect;

        if ((self.s.frame == FRAME_attak204)
                || (self.s.frame == FRAME_attak207)
                || (self.s.frame == FRAME_attak210))
            effect = Constants.EF_HYPERBLASTER;
        else
            effect = 0;
        Math3D.AngleVectors(self.s.angles, forward, right, null);
        Math3D.G_ProjectSource(self.s.origin,
                MonsterFlash.monster_flash_offset[flash_number], forward, right,
                start);

        Math3D.VectorCopy(self.enemy.s.origin, end);
        end[2] += self.enemy.viewheight;
        Math3D.VectorSubtract(end, start, dir);

        Monster.monster_fire_blaster(self, start, dir, 1, 1000, flash_number,
                effect);
    }

    /*
     * QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush
     * Trigger_Spawn Sight
     */
    public static void SP_monster_flyer(Entity self) {
        if (GameBase.deathmatch.value != 0) {
            GameUtil.G_FreeEdict(self);
            return;
        }

        // fix a map bug in jail5.bsp
        if (GameBase.level.mapname.equalsIgnoreCase("jail5")
                && (self.s.origin[2] == -104)) {
            self.targetname = self.target;
            self.target = null;
        }

        sound_sight = ServerInit.SV_SoundIndex("flyer/flysght1.wav");
        sound_idle = ServerInit.SV_SoundIndex("flyer/flysrch1.wav");
        sound_pain1 = ServerInit.SV_SoundIndex("flyer/flypain1.wav");
        sound_pain2 = ServerInit.SV_SoundIndex("flyer/flypain2.wav");
        sound_slash = ServerInit.SV_SoundIndex("flyer/flyatck2.wav");
        sound_sproing = ServerInit.SV_SoundIndex("flyer/flyatck1.wav");
        sound_die = ServerInit.SV_SoundIndex("flyer/flydeth1.wav");

        ServerInit.SV_SoundIndex("flyer/flyatck3.wav");

        self.s.modelindex = ServerInit.SV_ModelIndex("models/monsters/flyer/tris.md2");
        Math3D.VectorSet(self.mins, -16, -16, -24);
        Math3D.VectorSet(self.maxs, 16, 16, 32);
        self.movetype = Constants.MOVETYPE_STEP;
        self.solid = Constants.SOLID_BBOX;

        self.s.sound = ServerInit.SV_SoundIndex("flyer/flyidle1.wav");

        self.health = 50;
        self.mass = 50;

        self.pain = flyer_pain;
        self.die = flyer_die;

        self.monsterinfo.stand = flyer_stand;
        self.monsterinfo.walk = flyer_walk;
        self.monsterinfo.run = flyer_run;
        self.monsterinfo.attack = flyer_attack;
        self.monsterinfo.melee = flyer_melee;
        self.monsterinfo.sight = flyer_sight;
        self.monsterinfo.idle = flyer_idle;

        World.SV_LinkEdict(self);

        self.monsterinfo.currentmove = flyer_move_stand;
        self.monsterinfo.scale = MODEL_SCALE;

        GameAI.flymonster_start.think(self);
    }
}
